package com.universal_library.permission;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.util.Log;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

/**
 * Created by solin on 2018/1/30.
 */

public class AcpManager {
    private static final String TAG = "AcpManager";
    private static final int REQUEST_CODE_PERMISSION = 0x38;//申请权限
    private static final int REQUEST_CODE_SETTING = 0x39;//跳转设置

    private Context mContext;
    private Activity mActivity;
    private AcpService mService;
    private AcpOptions mOptions;
    private AcpListener mCallBack;

    private final List<String> mDeniedPermissions = new LinkedList<>();
    private final Set<String> mMaifestPermissions = new HashSet<>(1);

    public AcpManager(Context mContext) {
        this.mContext = mContext;
        mService = new AcpService();
        getMainfestPermissions();
    }

    /**
     * 获取msinfest 中的权限
     */
    private synchronized void getMainfestPermissions() {
        PackageInfo info = null;
        try {
            info = mContext.getPackageManager().getPackageInfo(
                    mContext.getPackageName(), PackageManager.GET_PERMISSIONS);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (info != null) {
            String[] permissions = info.requestedPermissions;
            if (permissions != null) {
                for (String perm : permissions) {
                    mMaifestPermissions.add(perm);
                }
            }
        }
    }

    /**
     * 开始请求权限
     *
     * @param options
     * @param listener
     */
    public synchronized void request(AcpOptions options, AcpListener listener) {
        mCallBack = listener;
        mOptions = options;
        checkSelfPermission();
    }

    /**
     * 检查权限
     */
    public synchronized void checkSelfPermission() {
        mDeniedPermissions.clear();
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            //小于 6.0
            Log.i(TAG, "系统版本小于……6.0");
            if (mCallBack != null)
                mCallBack.onGranted();
            onDestroy();
            return;
        }
        String[] permissions = mOptions.getPermissions();
        for (String perm : permissions) {
            //检查权限 是否在android Mainfest.xml 中
            if (mMaifestPermissions.contains(perm)) {
                int checkSelfPermission = mService.checkSelfPermission(mContext, perm);
                Log.i(TAG, "申请权限结果:" + checkSelfPermission);
                //如果是被拒绝的加入拒绝集合中
                if (checkSelfPermission == PackageManager.PERMISSION_DENIED) {
                    mDeniedPermissions.add(perm);
                }
            }
        }
        //检查若果没有一个拒绝相应 onGranted 回调
        if (mDeniedPermissions.isEmpty()) {
            Log.i(TAG, "mDeniedPermissions.isEmpty()");
            if (mCallBack != null)
                mCallBack.onGranted();
            onDestroy();
            return;
        }
        startAcpActivity();
    }

    /**
     * 启动处理权限过程的 Activity
     */
    private synchronized void startAcpActivity() {
        Intent intent = new Intent(mContext, AcpActivity.class);
        //新开已个任务栈
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        mContext.startActivity(intent);
    }

    /**
     * 摧毁本库的 AcpActivity
     */
    private void onDestroy() {
        if (mActivity != null) {
            mActivity.finish();
            mActivity = null;
        }
        mCallBack = null;
    }

    /**
     * 检查权限是否存在
     * 拒绝后不在提示
     *
     * @param activity
     */
    public synchronized void checkRequestPermissionRationale(Activity activity) {
        mActivity = activity;
        boolean rationale = false;
        //若果有拒绝则提示申请理由提示框，否则直接向系统申请权限
        for (String permission : mDeniedPermissions) {
            rationale = rationale || mService.shouldShowRequestPermissionRationale(activity, permission);
        }
        Log.i(TAG, "rationale = " + rationale);
        String[] permissions = mDeniedPermissions.toArray(new String[mDeniedPermissions.size()]);
        if (rationale)
            //拒绝的弹框提示 申请
            showRationalDialog(permissions);
        else
            //没有的直接申请
            requestPermissions(permissions);
    }

    /**
     * 申请权限理由对话框
     *
     * @param permissions
     */
    private synchronized void showRationalDialog(final String[] permissions) {
        new AlertDialog.Builder(mActivity).setMessage(mOptions.getRationalMessage())
                .setPositiveButton(mOptions.getRationalBtnText(), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        requestPermissions(permissions);
                    }
                }).show();
    }

    /**
     * 申请权限
     *
     * @param permissions
     */
    private synchronized void requestPermissions(String[] permissions) {
        mService.requestPermission(mActivity, permissions, REQUEST_CODE_PERMISSION);
    }

    /**
     * 响应系统请求权限结果
     *
     * @param requestCode  请求码
     * @param permissions  请求的集合
     * @param grantResults 结果的数组
     */
    public synchronized void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case REQUEST_CODE_PERMISSION:
                //同意的权限
                LinkedList<String> grantedPermission = new LinkedList<>();
                //拒绝的权限
                LinkedList<String> deniedPermission = new LinkedList<>();
                for (int i = 0; i < permissions.length; i++) {
                    String permission = permissions[i];
                    if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                        //申请成功
                        grantedPermission.add(permission);
                    } else {
                        //申请失败的
                        deniedPermission.add(permission);
                    }
                }
                //全部允许情况回调 onGranted 否则只要有一个拒绝则回调onDenied
                if (!grantedPermission.isEmpty() && deniedPermission.isEmpty()) {
                    if (mCallBack != null)
                        mCallBack.onGranted();
                    onDestroy();
                } else if (!deniedPermission.isEmpty()) {
                    showDeniedDialog(deniedPermission);
                }
                break;
        }
    }

    /**
     * 拒绝权限的提示框
     *
     * @param permission
     */
    private synchronized void showDeniedDialog(final List<String> permission) {
        new AlertDialog.Builder(mContext)
                .setMessage(mOptions.getDeniedMessage())
                .setCancelable(false)
                .setNegativeButton(mOptions.getDeniedCloseBtn(), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        if (mCallBack != null)
                            mCallBack.onDenied(permission);
                        onDestroy();
                    }
                })
                .setPositiveButton(mOptions.getDeniedSettingBtn(), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        startSetting();
                    }
                }).show();
    }

    /**
     * 跳转到设置页面
     */
    public void startSetting() {
        if (MiuiOs.isMIUI()) {
            Intent intent = MiuiOs.getSettingIntent(mActivity);
            if (MiuiOs.isIntentAvailable(mActivity, intent)) {
                mActivity.startActivityForResult(intent, REQUEST_CODE_SETTING);
                return;
            }
        }
        try {
            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                    .setData(Uri.parse("package:" + mActivity.getPackageName()));
            mActivity.startActivityForResult(intent, REQUEST_CODE_SETTING);
        } catch (Exception e) {
            e.printStackTrace();
            try {
                Intent intent = new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS);
                mActivity.startActivityForResult(intent, REQUEST_CODE_SETTING);
            } catch (Exception e1) {
                e1.printStackTrace();
            }

        }
    }

    /**
     * 相应设置权限返回结果
     *
     * @param requestCode 请求码
     * @param resultCode  结果码
     * @param data        数据
     */
    public synchronized void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (mCallBack != null || mOptions == null
                || requestCode != REQUEST_CODE_SETTING) {
            onDestroy();
            return;
        }
        checkSelfPermission();
    }
}
